package com.fy.controller;

import com.fy.common.annotation.GlobalInterceptor;
import com.fy.common.annotation.VerifyParam;
import com.fy.common.constants.Constants;
import com.fy.common.constants.MessageConstant;
import com.fy.ex.ConditionException;
import com.fy.ex.handler.ExceptionHandler;
import com.fy.mapper.EmailMapper;
import com.fy.pojo.entity.User;
import com.fy.pojo.vo.activity.ActiveUserVO;
import com.fy.pojo.vo.user.LoginUserVO;
import com.fy.pojo.vo.user.UserInfoVO;
import com.fy.pojo.vo.user.UserSpaceVO;
import com.fy.service.UserService;
import com.fy.utils.DateFormatter;
import com.fy.utils.RedisUtils;
import com.fy.utils.StringTools;
import com.fy.utils.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.*;

@Slf4j
// @Api("接口")
@RestController("userController")
public class UserController extends BaseController {

    @Autowired
    private UserService userService;

    @Autowired
    private RedisUtils redisUtils;

    /***
     * 用户注册
     *
     * @param httpSession
     * @param checkCode
     * @param emailCode
     * @param email
     * @param username
     * @param password
     * @return
     */
    @PostMapping("/register")
    @GlobalInterceptor(checkLogin = false, checkParams = true)
    public Result register(HttpServletRequest request, HttpSession httpSession, String checkCode, String emailCode,
            String email, @RequestParam("nickName") String username, String password) {
        log.info("信息为:{}", checkCode, emailCode, email, username, password);
        if (checkCode.equalsIgnoreCase((String) httpSession.getAttribute(Constants.CHECK_CODE))) {
            userService.register(request, email, emailCode, username, password);
            httpSession.removeAttribute(Constants.CHECK_CODE);
            return Result.success();
        } else {
            httpSession.removeAttribute(Constants.CHECK_CODE);
            throw new ConditionException(MessageConstant.GRAPHIC_CAPTCHA_ERROR);
        }

    }

    /**
     * 用户登录
     */
    @PostMapping("/login")
    @GlobalInterceptor(checkLogin = false, checkParams = true)
    public Result login(HttpServletRequest request, HttpSession session,
            @RequestParam String checkCode,
            @RequestParam(required = false) String email,
            @RequestParam(required = false) String username,
            @RequestParam String password) {
        log.info("登录信息: 验证码: {}, 邮箱: {}, 用户名: {}, 密码: {}", checkCode, email, username, password);

        // 验证码校验 todo
        // if (!checkCode.equalsIgnoreCase((String)
        // httpSession.getAttribute(Constants.CHECK_CODE))) {
        // httpSession.removeAttribute(Constants.CHECK_CODE);
        // throw new CheckCodeErrorException(MessageConstant.GRAPHIC_CAPTCHA_ERROR);
        // }

        // 登录处理
        LoginUserVO loginUserVO = userService.login(request, email, username, password);

        // 设置session过期时间为7天
        session.setMaxInactiveInterval(7 * 24 * 60 * 60);
        session.setAttribute(Constants.SESSION_KEY, loginUserVO);
        session.removeAttribute(Constants.CHECK_CODE);

        return Result.success(loginUserVO);
    }

    /**
     * 修改密码
     *
     * @param password
     * @param httpSession
     * @return
     */
    @GlobalInterceptor(checkParams = true)
    @PostMapping("/updatePassword")
    public Result updatePassword(String password, HttpSession httpSession) {
        log.info("(修改密码)新密码:{}", password);
        String md5Password = StringTools.getPasswordDD5String(password);
        log.info("md5加密的新密码:{}", md5Password);
        LoginUserVO loginUserVO = (LoginUserVO) httpSession.getAttribute(Constants.SESSION_KEY);
        log.info("session用户数据:{}", loginUserVO);
        userService.updatePassword(loginUserVO.getNickName(), md5Password);
        return Result.success();
    }

    /**
     * 重置密码
     *
     * @param newPassword
     * @param email
     * @param httpSession
     * @return
     */
    @PostMapping("/resetPwd")
    @GlobalInterceptor(checkLogin = false, checkParams = true)
    public Result resetPwd(@RequestParam("password") String newPassword, String email, String checkCode,
            String emailCode,
            HttpSession httpSession) {
        log.info("找回密码的用户信息: 验证码: {}, 邮箱: {}, 新密码: {}, 邮箱验证码: {}", checkCode, email, newPassword, emailCode);
        if (!checkCode.equalsIgnoreCase((String) httpSession.getAttribute(Constants.CHECK_CODE))) {
            httpSession.removeAttribute(Constants.CHECK_CODE);
            throw new ConditionException(MessageConstant.GRAPHIC_CAPTCHA_ERROR);
        } else {
            userService.resetPwd(email, emailCode, newPassword);
            return Result.success();
        }
    }

    /**
     * 获取用户空间信息
     *
     * @param httpSession
     * @return
     */
    @PostMapping("/getUseSpace")
    @GlobalInterceptor(checkLogin = true, checkParams = true)
    public Result getUseSpace(HttpSession httpSession) {
        LoginUserVO loginUserVO = (LoginUserVO) httpSession.getAttribute(Constants.SESSION_KEY);
        log.info("object:{}", loginUserVO);
        log.info("会话id:{}", httpSession.getId());
        String nickName = loginUserVO.getNickName();
        UserSpaceVO userSpaceVO = userService.getUserSpace(nickName);
        log.info("查询到的用户空间信息:{}", userSpaceVO);
        return Result.success(userSpaceVO);
    }

    /**
     * 更新头像
     *
     * @param httpSession
     * @param response
     * @param avatar
     * @return
     */
    @PostMapping("/updateUserAvatar")
    @GlobalInterceptor(checkLogin = true, checkParams = true)
    public Result updateUserAvatar(HttpSession httpSession, HttpServletResponse response, MultipartFile avatar) {

        LoginUserVO loginUserVO = (LoginUserVO) httpSession.getAttribute(Constants.SESSION_KEY);
        String userEmail = loginUserVO.getUserId();

        response.setContentType("image/jpg");

        // 读取文件并将其内容发送到客户端。
        log.info("更新的用户id和头像信息:{},{}", userEmail, avatar.getOriginalFilename());
        String path = userService.updateAvatarPath(userEmail, avatar);
        log.info("获取到的头像文件路径:{}", path);
        return Result.success(path);
    }

    /**
     * 获取用户头像
     *
     * @param response
     * @param userEmail
     */
    @GetMapping("/getAvatar/{userId}")
    @GlobalInterceptor
    public void getAvatar(HttpServletResponse response,
            @VerifyParam(required = true) @PathVariable("userId") String userEmail) {
        String dataAvatarPath = userService.getAvatar(userEmail);
        response.setContentType("image/jpg");
        readFile(response, dataAvatarPath);
    }

    /**
     * 退出登录
     *
     * @param httpSession
     * @return
     */
    @PostMapping("/logout")
    public Result logout(HttpSession httpSession) {
        Object sessionObject = httpSession.getAttribute(Constants.SESSION_KEY);
        if (sessionObject != null && sessionObject instanceof LoginUserVO) {
            LoginUserVO loginUserVO = (LoginUserVO) sessionObject;
            String username = loginUserVO.getNickName();
            userService.logout(username);
            log.info("退出登录前获取的用户姓名:{}", username);
            // 清除特定的会话属性
            httpSession.invalidate();

            // 清除用户相关空间缓存
            redisUtils.delete(username + "Space");
            return Result.success(null);
        } else {
            return Result.success(null);
        }
    }

    /**
     * 注销账号
     *
     * @param httpSession
     * @return
     */
    @PostMapping("/user/destroy")
    @GlobalInterceptor
    public Result destroy(HttpSession httpSession) {
        LoginUserVO loginUserVO = (LoginUserVO) httpSession.getAttribute(Constants.SESSION_KEY);
        ExceptionHandler.throwIf(loginUserVO.getAdmin(), "管理员账号不能注销!");
        log.info("注销用户:{}", loginUserVO.getNickName());
        userService.destroy(loginUserVO);
        String username = loginUserVO.getNickName();
        userService.logout(username);
        log.info("退出登录前获取的用户姓名:{}", username);
        // 清除特定的会话属性
        httpSession.invalidate();
        // 清除用户相关空间缓存
        redisUtils.delete(username + "Space");
        return Result.success();
    }

    @PostMapping("/user/getDailyCheck")
    public Result getDailyCheck() {
        // ... 实现逻辑
        return Result.success();
    }

    @PostMapping("/user/activeRanking")
    public Result getActiveUsers() {
        List<User> activeUsers = userService.list();
        List<ActiveUserVO> activeUserVO = new ArrayList<>();
        activeUsers.forEach(user -> {
            ActiveUserVO a = new ActiveUserVO();
            a.setUserId(user.getUserId());
            a.setNickName(user.getUsername());
            a.setAvatar(user.getAvatar());
            a.setPoints(Math.toIntExact(user.getPoint()));
            activeUserVO.add(a);

        });
        return Result.success(activeUserVO);
    }

    /**
     * 用户签到
     *
     * @param session
     * @return
     */
    @PostMapping("/user/checkIn")
    @GlobalInterceptor
    public Result checkIn(HttpSession session) {
        LoginUserVO loginUserVO = (LoginUserVO) session.getAttribute(Constants.SESSION_KEY);
        return userService.checkIn(Math.toIntExact(loginUserVO.getId()));
    }

    /**
     * 获取用户信息
     * 
     * @return Result<UserInfoVO>
     */
    @Autowired
    private EmailMapper emailMapper;

    @PostMapping("/getUserInfo")
    public Result<UserInfoVO> getUserInfo(HttpSession httpSession) {
        LoginUserVO loginUserVO = (LoginUserVO) httpSession.getAttribute(Constants.SESSION_KEY);
        log.info("获取用户信息，用户id={}", loginUserVO.getId());
        User user = userService.getById(loginUserVO.getId());
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(user, userInfoVO);
        userInfoVO.setEmail(emailMapper.selectById(user.getEmailId()).getEmail());
        return Result.success(userInfoVO);

    }

    /**
     * 获取用户信息
     *
     * @param userId
     * @return
     */
    @PostMapping("/user/profile")
    @GlobalInterceptor(checkParams = true)
    public Result getUserProfile(@RequestParam Integer userId) {
        log.info("获取用户信息，userId={}", userId);
        return userService.getUserProfile(userId);
    }

    @PostMapping("/updateSpacePermission")
    @GlobalInterceptor(checkLogin = true)
    public Result updateSpacePermission(HttpSession session, @RequestParam("spaceEnabled") Boolean spaceEnabled) {
        LoginUserVO loginUserVO = (LoginUserVO) session.getAttribute(Constants.SESSION_KEY);
        userService.updateSpacePermission(loginUserVO.getId(), spaceEnabled);
        return Result.success();
    }

    /**
     * QQ登录回调接口
     */
    @PostMapping("/qqLogin")
    @GlobalInterceptor(checkLogin = false)
    public Result qqLogin(HttpServletRequest request,
            @RequestParam(required = false) String code,
            @RequestParam(required = false) String state) {
        log.info("收到QQ登录回调, code: {}, state: {}", code, state);

        // 这里是测试数据，实际使用时需要:
        // 1. 通过code获取access_token
        // 2. 通过access_token获取用户信息
        // 3. 保存或更新用户信息
        // 4. 生成登录态

        if (code == null || state == null) {
            return Result.error("QQ登录参数错误");
        }

        // 模拟返回登录成功的用户信息
        Map<String, Object> data = new HashMap<>();
        data.put("提醒","以下均为测试数据,具体功能以QQ开放平台申请通过可实现!!!");
        data.put("nickname", "QQ用户_" + UUID.randomUUID().toString().substring(0, 6));
        data.put("avatar", "https://fypan.oss-cn-hangzhou.aliyuncs.com/3499802689.jpg");
        data.put("openid", UUID.randomUUID().toString());
        data.put("loginTime", DateFormatter.getNowDateTimeString());

        // 记录日志
        log.info("QQ登录成功，用户信息: {}", data);

        return Result.success(data);
    }

}
